
#import "Tex.h"

@implementation Tex

- (void) createTexFromImage: (NSString *) picName {     
    UIImage *pic = [UIImage imageNamed: picName];
	
	int scaleFactor = 1; 
	
	float iOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (iOSVersion >= 4.0) {
        if (pic.scale >= 2) {
            scaleFactor = pic.scale;
        }
    } 
	
    if (pic) {
        width = pic.size.width * scaleFactor;
        height = pic.size.height * scaleFactor;
        if ( (width & (width-1)) != 0 || (height & (height-1)) != 0 
            || width > 2048 || height > 2048) {
            NSLog(@"ERROR: %@ width and/or height is not a power of 2 or > 2048!", picName); 
        }  
        
        GLubyte *pixelData = [self generatePixelDataFromImage: pic];    
    
        [self generateTexture: pixelData]; 
                
        int memory = width*height*4;
        NSLog(@"%@-Pic-Texture created, Size: %i KB, ID: %i", picName, memory/1024, textureID);
        free(pixelData);
						
		width /= scaleFactor;
        height /= scaleFactor;
    } else {
         NSLog(@"ERROR: %@ not found.", picName);
    }
}

- (void) createTexFromString: (NSString *) text {    
    int len = [text length]*20;
    if (len < 64) width = 64;
    else if (len < 128) width = 128;
    else if (len < 256) width = 256;
    else width = 512; //max width text    
    height = 32;    
    
    GLubyte *pixelData = [self generatePixelDataFromString: text];
        
    [self generateTexture: pixelData]; 
    
    //Cleanup
    int memory = width*height*4;
    NSLog(@"%@-Text-Texture created, Size: %i KB, ID: %i", text, memory/1024, textureID);
    free(pixelData);
}

- (GLubyte *) generatePixelDataFromImage: (UIImage *) pic {     
    GLubyte *pixelData = (GLubyte *) calloc( width*height*4, sizeof(GLubyte) );
    CGColorSpaceRef imageCS = CGImageGetColorSpace(pic.CGImage);
    CGContextRef gc = CGBitmapContextCreate( pixelData, 
                                             width, height, 8, width*4,                                                       
                                             imageCS, 
                                             kCGImageAlphaPremultipliedLast);
    CGContextDrawImage(gc, CGRectMake(0, 0, width, height), pic.CGImage);  
    CGContextRelease(gc);    
    return pixelData;    
}

- (GLubyte *) generatePixelDataFromString: (NSString *) text {   
    const char *cText = [text cStringUsingEncoding: NSASCIIStringEncoding];
    GLubyte *pixelData = (GLubyte *) calloc( width*height*4, sizeof(GLubyte) );
    CGColorSpaceRef rgbCS = CGColorSpaceCreateDeviceRGB();
    CGContextRef gc = CGBitmapContextCreate( pixelData, 
                                             width, height, 8, width*4,                                                       
                                             rgbCS, 
                                             kCGImageAlphaPremultipliedLast);        
    int size = 22; 
    CGContextSetRGBFillColor(gc, 0,1,0,1);
    CGContextSelectFont(gc, "Verdana", size, kCGEncodingMacRoman);
    int ys = height-size; //swapped y-axis
    CGContextShowTextAtPoint(gc, 0, ys, cText, strlen(cText)); 
    CGColorSpaceRelease(rgbCS);
    CGContextRelease(gc);    
    return pixelData;
} 

- (void) generateTexture: (GLubyte *) pixelData {
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);                     
    
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

- (void) drawAt: (CGPoint) p {
    GLshort imageVertices[ ] = {                 
        0,      height, 
        width,  height, 
        0,      0,      
        width,  0         
    };        
    
    GLshort textureCoords[ ] = {                 
        0, 1, 
        1, 1, 
        0, 0, 
        1, 0                       
    };
    
	p.x = (int) p.x;
    p.y = (int) p.y;
	
    glEnable(GL_TEXTURE_2D);  
    
    glColor4f(1, 1, 1, 1);
    glBindTexture(GL_TEXTURE_2D, textureID); 
    glVertexPointer(2, GL_SHORT, 0, imageVertices);	
    glTexCoordPointer(2, GL_SHORT, 0, textureCoords);    
    
    glPushMatrix();
    glTranslatef(p.x, p.y, 0);    
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 
    glPopMatrix();
    
    glDisable(GL_TEXTURE_2D);    
}

- (void) drawFrame: (int) frameNr 
        frameWidth: (int) fw
             angle: (int) degrees
                at: (CGPoint) p {
    
    GLshort imageVertices[ ] = {                 
        0,   height, 
        fw,  height,
        0,   0,      
        fw,  0         
    };        
    
    GLfloat txW = 1.0/(width/fw);    
    GLfloat x1  = frameNr*txW;
    GLfloat x2 =  x2  = x1 + txW; //or: x2 = (frameNr + 1) * txW;
    GLfloat textureCoords[ ] = {                 
        x1,  1,
        x2,  1, 
        x1,  0, 
        x2,  0                       
    };
    
    glEnable(GL_TEXTURE_2D);   
    
    glColor4f(1, 1, 1, 1);
    glBindTexture(GL_TEXTURE_2D, textureID); 
    glVertexPointer(2, GL_SHORT, 0, imageVertices);	
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);    
    
    glPushMatrix();
    glTranslatef(p.x+fw/2, p.y+height/2, 0);    
    glRotatef(degrees, 0, 0, 1); //angle = 0 => no rotation
    glTranslatef(0-fw/2, 0-height/2, 0);   
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);         
    glPopMatrix();
    
    glDisable(GL_TEXTURE_2D);  
}

- (GLuint) getTextureID {
    return textureID;
}

- (int) getWidth {
    return width;
}

- (int) getHeight {
    return height;
}

- (void) dealloc {
    NSLog(@"Delete texture, ID: %i", textureID);
    glDeleteTextures(1, &textureID);
    [super dealloc];
}

@end
